<?php
/**
 * Created by PhpStorm.
 * User: Thai Dac Vinh
 * Date: 9/18/14
 * Time: 6:34 PM
 */
//libxml_disable_entity_loader(false);

/**
 * Abstract Class Vocab
 */
abstract class Vocab {
    public $assoc_data;
    public $learned_data;
    public $card_count;
    public $card_learned_count = 0;
    public $card_tested_correct_count = 0;
    public $card_tested_incorrect_count = 0;
    public function __construct() {
        $this->assoc_data = null;
        $this->_fetch_vocab();
        if ($this->assoc_data != null) {
            $this->card_count = $this->count_card();
        }
    }
    abstract protected function _fetch_vocab();
    function count_card() {
        $count = 0;
        foreach ($this->assoc_data as $month_cards) {
            $count += sizeof($month_cards);
        }
        return $count;
    }
}

/**
 * Class Google Site - Thai Dac Vinh's Vocabulary
 */
class GS_TDV_Vocab extends Vocab {
    private $base_url = 'https://sites.google.com/site/thaidacvinh4english/vocabulary/';
    private $page_name;
    private $page_url;
    private $card_info;
    public function __construct($page_name = null, $card_info = null) {
        global $year_default;
        if ($page_name == null) $page_name = $year_default;
        $this->page_name = $page_name;
        $this->page_url = $this->base_url . $this->page_name;
        $this->card_info = $card_info;
        if ($card_info != null) {
            $this->card_learned_count = sizeof($card_info);
            if (isset($card_info["{$this->page_name}-correct"])) $this->card_tested_correct_count = $card_info["{$this->page_name}-correct"];
            if (isset($card_info["{$this->page_name}-correct"])) $this->card_tested_incorrect_count = $card_info["{$this->page_name}-incorrect"];
        }
        parent::__construct();
    }

    public function update_card_info($card_info) {
        $this->card_info = $card_info;
        if ($card_info != null) {
            $this->card_learned_count = sizeof($card_info);
            if (isset($card_info["{$this->page_name}-correct"])) $this->card_tested_correct_count = $card_info["{$this->page_name}-correct"];
            if (isset($card_info["{$this->page_name}-correct"])) $this->card_tested_incorrect_count = $card_info["{$this->page_name}-incorrect"];
        }
        // Update learned_data (used in test page)
        foreach ($this->assoc_data as $month => $days) {
            foreach ($days as $day => $day_vocab) {
                $wi_key = "{$month}-{$day}";
                if (isset($this->card_info[$wi_key]) && ($this->card_info[$wi_key] > 0)) {
                    $this->assoc_data[$month][$day]['learned_count'] = $this->card_info[$wi_key];
                    $this->learned_data = array();
                    foreach ($day_vocab['words'] as $word) {
                        $word['month'] = $month;
                        $word['day'] = $day;
                        $word['learned'] = $this->assoc_data[$month][$day]['learned_count'];
                        $this->learned_data[] = $word;
                    }
                }
            }
        }
    }

    /**
     * @return bool
     */
    protected function _fetch_vocab() {
        $doc = new DOMDocument();
        $page_content = $this->_fetch_remote_page_content();
        if ($doc->loadHTML($page_content)) {
            $xpath = new DOMXPath($doc);
            $content_root = $xpath->query("//td[contains(normalize-space(@class), 'sites-layout-tile')]/div[contains(normalize-space(@dir), 'ltr')]");
            if ($content_root->length > 0) {
                $content_root = $content_root->item(0);
                $items = $xpath->query(".//h1|.//h2|.//h3|.//h4|.//h5|.//h6|.//div", $content_root);
                $this->assoc_data = array();
                $this->learned_data = array();
                if ($items->length > 0) {
                    $month = 0;
                    foreach ($items as $item) {
                        if (preg_match('/^h\d$/', $item->tagName)) {
                            $month = $item->textContent;
                        } else {
                            $matched = preg_match('/^(\d+): (.*)/', $item->textContent, $matches);
                            if($matched) {
                                $day = $matches[1];
                                $day_words = $this->_explore_day_words($matches[2]);
                                $wi_key = "{$month}-{$day}";
                                $this->assoc_data[$month][$day]['words'] = $day_words;
                                $this->assoc_data[$month][$day]['learned_count'] = 0;
                                if (isset($this->card_info[$wi_key]) && ($this->card_info[$wi_key] > 0)) {
                                    $this->assoc_data[$month][$day]['learned_count'] = $this->card_info[$wi_key];
                                    foreach ($day_words as $word) {
                                        $word['month'] = $month;
                                        $word['day'] = $day;
                                        $word['learned'] = $this->assoc_data[$month][$day]['learned_count'];
                                        $this->learned_data[] = $word;
                                    }
                                }
                            }
                        }
                    }
                }
                return true;
            }
        }
        return false;
    }

    /**
     * Fetch page content from remote url
     * @return mixed|string
     */
    private function _fetch_remote_page_content() {
        $page_url = $this->page_url;
        $page_content = file_get_contents($page_url);
        $page_content = str_replace('<meta http-equiv="X-UA-Compatible" content="chrome=1" />', '<meta http-equiv="Content-type" content="text/html; charset=utf-8" />', $page_content);
        return $page_content;
    }

    /**
     * @param $day_words
     * @return array
     */
    private function _explore_day_words ($day_words) {
        $regex_t = '#/([^/]*)/#';
        $sub_rec_regex = '(\\(((?>[^()]+)|(?-2))*\\))';
        if (preg_match_all($regex_t, $day_words ,$matches)) {
            $regex = "#((([^/])|(\\\\/))+)/([^/]*)/{$sub_rec_regex}(\\([^\\)]*\\))?([, ]*)#";// MAIN REGULAR EXPRESSION HERE
            if (preg_match_all($regex, $day_words ,$matches)) {
                $day_words = $matches[0];
                foreach ($day_words as $key => $word) {
                    preg_match($regex, $word, $matches);
                    $word_bare = $matches[1];
                    $word = str_replace('\\/', '/', $word_bare);
                    $decorated_word = $word;
                    $trans = $matches[2];
                    $meaning = preg_replace('#(\()(.*)(\))#', '$2', $matches[6]);
                    $note = preg_replace('#\((.*)\)#', '$1', $matches[8]);
                    if ($note == null) {
                        $note == '';
                    } else {
                        $decorated_word = '<span class="link">' . $word . '</span>';
                        if ($note == 'jpg' || $note == 'png' || $note == 'gif') {
                            $decorated_word .= '&nbsp;<span class="glyphicon glyphicon-picture"></span>';
                            $image_src = $this->page_url . '/' . $word . '.' . $note;
                            $note = '<img class="note_img" src="' . $image_src . '" />';
                        } else {
                            $decorated_word .= '&nbsp;<span class="glyphicon glyphicon-comment"></span>';
                            $note = preg_replace("/{$word_bare}/", '<strong>' . $word . '</strong>', $note);
                        }
                    }
                    $day_words[$key] = array(
                        'word' => $word,
                        'decorated_word' => $decorated_word,
                        'trans' => $trans, 'meaning' => $meaning, 'learned' => 0, 'note' => $note);
                }
                return $day_words;
            }
        } else {
            $regex = "#([^()]+){$sub_rec_regex}([, ]*)#";
            if (preg_match_all($regex, $day_words ,$matches)) {
                $day_words = $matches[0];
                foreach ($day_words as $key => $word) {
                    preg_match($regex, $word, $matches);
                    $word = $matches[1];
                    $meaning = preg_replace('#(\()(.*)(\))#', '$2', $matches[2]);
                    $day_words[$key] = array('word' => $word,
                        'decorated_word' => $word, 'trans' => '', 'meaning' => $meaning, 'learned' => 0);
                }
                return $day_words;
            }
        }
        return array();
    }
}